{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 👋🌍 Hello, world: Submit a Q# job to IonQ\n",
    "\n",
    "In this notebook, we'll review the basics of Azure Quantum by submitting a simple *job*, or quantum program, to [IonQ](https://ionq.com/). We will use [Q#](https://docs.microsoft.com/azure/quantum/user-guide/) to express the quantum job."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "## Submit a simple job to IonQ using Azure Quantum\n",
    "Azure Quantum provides several ways to express quantum programs. In this example we are using Q#, but note that Qiskit and Cirq are also supported. All code in this example will be written in Python and Q#.\n",
    "\n",
    "Let's begin. When you see a code block, hover over it and click the triangle play-button to execute it. To avoid any compilation issues, this should be done in order from top to bottom."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 1. Connect to the Azure Quantum workspace\n",
    "\n",
    "To connect to the Azure Quantum service, call the `connect` function as seen below. This can take 30 seconds to run the first time, as the Q# environment is initializing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import qsharp.azure\n",
    "\n",
    "targets = qsharp.azure.connect(\n",
    "   resourceId=\"\",\n",
    "   location=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "We can use the resulting object to see which _targets_ are available for submission."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "import qsharp\n",
    "\n",
    "print(\"This workspace's targets:\")\n",
    "for target in targets:\n",
    "    print(\"-\", target.id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### ❕ Do you see `ionq.simulator` in your list of targets? If so, you're ready to keep going.\n",
    "\n",
    "Don't see it? You may need to add IonQ to your workspace to run this sample. Navigate to the **Providers** page in the portal and click **+Add** to add the IonQ provider. Don't worry, there's a free credits plan available."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "## IonQ: The quantum provider\n",
    "Azure Quantum partners with third-party companies to deliver solutions to quantum jobs. These company offerings are called *providers*. Each provider can offer multiple *targets* with different capabilities. See the table below for IonQ's targets.\n",
    "\n",
    "| Target name | Target ID | Number of qubits | Description |\n",
    "| --- | --- | --- | --- |\n",
    "| Quantum simulator | `ionq.simulator` | 29 qubits | IonQ's cloud-based idealized simulator. Free of cost. |\n",
    "| Aria 1 | `ionq.qpu.aria-1` | 23 qubits | IonQ's Aria 1 trapped-ion quantum computer. This is real quantum hardware, not a simulation. |\n",
    "| Quantum computer | `ionq.qpu` | 11 qubits | IonQ's trapped-ion quantum computer. This is real quantum hardware, not a simulation. |\n",
    "\n",
    "For this example, we will use `ionq.simulator`. To learn more about IonQ's targets, check out our [documentation](https://docs.microsoft.com/azure/quantum/provider-ionq)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Build the quantum program\n",
    "\n",
    "Let's create a simple Q# program to run. This can take 30 seconds to run the first time, as the Q# environment is initializing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "# We declare the function we will define in Q# as a callable so that Python recognizes the symbol.\n",
    "GenerateRandomBit: any = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "microsoft": {
     "language": "qsharp"
    }
   },
   "outputs": [],
   "source": [
    "%%qsharp\n",
    "open Microsoft.Quantum.Measurement;\n",
    "open Microsoft.Quantum.Arrays;\n",
    "open Microsoft.Quantum.Convert;\n",
    "\n",
    "operation GenerateRandomBit() : Result {\n",
    "    use target = Qubit();\n",
    "\n",
    "    // Apply an H-gate and measure.\n",
    "    H(target);\n",
    "    return M(target);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The program you built is a simple quantum random bit generator. With IonQ's idealized simulator, we will be able to calculate the probability of measuring a `1` or `0`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Submit the quantum program to IonQ\n",
    "\n",
    "We will use the `execute` function to run the quantum program above on IonQ's `ionq.simulator` target. This may take a minute or so ⏳. Your job will be packaged and sent to IonQ, where it will wait its turn to be run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the target to ionq.simulator\n",
    "qsharp.azure.target(\"ionq.simulator\")\n",
    "\n",
    "# We'll use 100 shots (simulated runs). Timeout is in seconds.\n",
    "result = qsharp.azure.execute(GenerateRandomBit, shots=100, jobName=\"Generate one random bit\", timeout=240)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The job ID can be used to retrieve the results later using the `output` and `status` functions or by viewing it under the **Job management** section of the portal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 4. Visualize job results \n",
    "You can also view a histogram of the results using [`pyplot`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.html):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "from matplotlib import pyplot\n",
    "\n",
    "pyplot.bar(result.keys(), result.values())\n",
    "pyplot.title(\"Result\")\n",
    "pyplot.xlabel(\"Measurement\")\n",
    "pyplot.ylabel(\"Probability\")\n",
    "\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "**See the histogram above? Congratulations, you've submitted a job with Azure Quantum! 👏**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 5. Next steps\n",
    "Next, you can try running a program on IonQ's hardware target - just replace `ionq.simulator` with `ionq.qpu`. Or try another sample by navigating back to the sample gallery. The same \"hello world\" sample can be run with different quantum providers by choosing another option in the gallery card drop-down menu. Don't worry - your work here is automatically saved.\n",
    "\n",
    "To learn more about submitting jobs to Azure Quantum using Q#, refer to [this documentation](https://docs.microsoft.com/azure/quantum/how-to-submit-jobs?pivots=ide-python).\n",
    "\n",
    "To learn more about job pricing, review the [Azure Quantum documentation on job costs](https://docs.microsoft.com/azure/quantum/azure-quantum-job-costs)."
   ]
  }
 ],
 "metadata": {
  "kernel_info": {
   "name": "python3"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nteract": {
   "version": "nteract-front-end@1.0.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
